package cn.exrick.xboot.modules.activiti.controller.business;

import cn.exrick.xboot.common.constant.ActivitiConstant;
import cn.exrick.xboot.modules.activiti.entity.ActProcess;
import cn.exrick.xboot.modules.activiti.service.ActProcessService;
import cn.exrick.xboot.modules.activiti.vo.ActPage;
import cn.exrick.xboot.modules.activiti.vo.ProcessNodeVo;
import cn.exrick.xboot.modules.activiti.vo.TaskVo;
import cn.exrick.xboot.modules.base.entity.Department;
import cn.exrick.xboot.modules.base.entity.Role;
import cn.exrick.xboot.modules.base.entity.User;
import cn.exrick.xboot.modules.base.service.DepartmentService;
import cn.exrick.xboot.modules.base.service.UserService;
import cn.hutool.core.date.DateUtil;
import com.alibaba.fastjson.JSON;
import io.swagger.annotations.ApiParam;
import org.activiti.engine.RuntimeService;
import org.activiti.engine.TaskService;
import org.activiti.engine.runtime.ProcessInstance;
import org.activiti.engine.task.IdentityLink;
import org.activiti.engine.task.Task;
import org.activiti.engine.task.TaskQuery;
import org.reflections.util.Utils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.data.domain.Page;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.web.bind.annotation.*;

import cn.exrick.xboot.base.XbootBaseController;
import cn.exrick.xboot.common.utils.PageUtil;
import cn.exrick.xboot.common.utils.ResultUtil;
import cn.exrick.xboot.common.utils.SecurityUtil;
import cn.exrick.xboot.common.vo.PageVo;
import cn.exrick.xboot.common.vo.Result;
import cn.exrick.xboot.common.vo.SearchVo;
import cn.exrick.xboot.modules.activiti.entity.ActBusiness;
import cn.exrick.xboot.modules.activiti.entity.business.Matter;
import cn.exrick.xboot.modules.activiti.service.ActBusinessService;
import cn.exrick.xboot.modules.activiti.service.business.MatterService;
import cn.hutool.core.util.StrUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import lombok.extern.slf4j.Slf4j;

import java.util.*;

/**
 * @author lihuan
 */
@Slf4j
@RestController
@Api(description = "事项流转管理接口")
@RequestMapping("/xboot/matter")
@Transactional
public class MatterController extends XbootBaseController<Matter, String> {

	@Autowired
	private MatterService matterService;

	@Autowired
	private ActProcessService actProcessService;

	@Override
	public MatterService getService() {
		return matterService;
	}

	@Autowired
	private TaskService taskService;

	@Autowired
	private ActBusinessService actBusinessService;

	@Autowired
	private DepartmentService departmentService;

	@Autowired
	private SecurityUtil securityUtil;

	@Autowired
	private UserService userService;


	@Autowired
	private RuntimeService runtimeService;


	@RequestMapping(value = "/getByCondition", method = RequestMethod.GET)
	@ApiOperation(value = "多条件分页获取")
	public Result<Page<Matter>> getByCondition(@ModelAttribute Matter matter, @ModelAttribute SearchVo searchVo,
			@ModelAttribute PageVo pageVo) {

		Page<Matter> page = matterService.findByCondition(matter, searchVo, PageUtil.initPage(pageVo));
		for (Matter obj : page.getContent()) {
			// 关联流程表 查询关联流程状态和结果等信息
			if (StrUtil.isNotBlank(obj.getActBusinessId())) {
				ActBusiness actBusiness = actBusinessService.get(obj.getActBusinessId());
				obj.setStatus(actBusiness.getStatus());
				obj.setResult(actBusiness.getResult());
				obj.setApplyTime(actBusiness.getApplyTime());
				obj.setRouteName(actBusiness.getRouteName());
				obj.setProcInstId(actBusiness.getProcInstId());
			}
		}
		return new ResultUtil<Page<Matter>>().setData(page);
	}

	@RequestMapping(value = "/add", method = RequestMethod.POST)
	@ApiOperation(value = "添加事项流转")
	public Result<Object> add(@ModelAttribute Matter matter, @RequestParam String procDefId) {

		Matter obj = matterService.save(matter);
		// 保存至我的申请业务
		String userId = securityUtil.getCurrUser().getId();
		ActBusiness actBusiness = new ActBusiness();
		actBusiness.setUserId(userId);
		// 记录关联业务表ID
		actBusiness.setTableId(obj.getId());
		actBusiness.setProcDefId(procDefId);
		actBusiness.setTitle(matter.getOrderTitle());
		//初始化流程排他数据.field0023是否满意，field0034是否解决
		actBusiness.getParams().put("field0023", "");
		actBusiness.getParams().put("field0034", "");
		if (Utils.isEmpty(obj.getField0001())){
			obj.setField0001("电[" + DateUtil.thisYear() + "]B-" + String.format("%07d",Long.valueOf(matterService.getTotalCount())));
		}
		actBusiness.setWorkId(obj.getField0001());
		ActBusiness a = actBusinessService.save(actBusiness);
		// 记录关联流程状态表ID
		obj.setActBusinessId(a.getId());
		matterService.update(obj);
		return new ResultUtil<Object>().setSuccessMsg("操作成功");
	}

	@RequestMapping(value = "/updateAndAct", method = RequestMethod.PUT)
	@ResponseBody
	@ApiOperation(value = "更新数据")
	public Result<Object> updateAndAct(@ModelAttribute Matter matter){
		update(matter);
		if (StrUtil.isNotBlank(matter.getProcInstId())){
			ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(matter.getProcInstId()).singleResult();
			if (pi != null && StrUtil.isNotBlank(pi.getBusinessKey())){
				ActBusiness actBusiness = actBusinessService.get(pi.getBusinessKey());
				Map<String, Object> params = new HashMap<>(16);
				//是否满意
				if (matter.getField0023() != null){
					actBusiness.getParams().put("field0023",matter.getField0023());
					params.put("field0023",matter.getField0023());
				}
				//是否解决
				if (matter.getField0034() != null){
					actBusiness.getParams().put("field0034",matter.getField0034());
					params.put("field0034",matter.getField0034());
				}
				actBusinessService.update(actBusiness);
				taskService.setVariables(matter.getActBusinessId(),params);
			}
		}
		return new ResultUtil<Object>().setSuccessMsg("操作成功");
	}


	@RequestMapping(value = "/updateValue/{tableId}", method = RequestMethod.GET)
	@ApiOperation(value = "更新数据")
	public Result<Object> checkValue(@ApiParam("流程定义id") @PathVariable String tableId, @RequestParam String field0012,@RequestParam String field0028,@RequestParam(required = false) String field0018){
		Matter matter = matterService.get(tableId);
		if (StrUtil.isBlank(matter.getField0007())){
			return new ResultUtil<Object>().setErrorMsg("问题分类不能为空,请先编辑!");
		}
		if (StrUtil.isBlank(matter.getField0031())) {
			return new ResultUtil<Object>().setErrorMsg("问题发生地址不能为空,请先编辑!");
		}
		if (StrUtil.isBlank(matter.getField0027())){
			return new ResultUtil<Object>().setErrorMsg("责任科室不能为空,请先编辑");
		}
		if (StrUtil.isNotBlank(field0018)){
			matter.setField0018(field0018);
		}
		if (StrUtil.isNotBlank(field0012)){
			matter.setField0012(field0012);
		}
		if (StrUtil.isNotBlank(field0028)){
			matter.setField0028(field0028);
		}

		return new ResultUtil<Object>().setSuccessMsg("操作成功");
	}
	@RequestMapping(value = "/updateByActid", method = RequestMethod.POST)
	@ApiOperation(value = "更新流程表信息")
	public Result<Object> updateByActid(@ModelAttribute Matter matter) {
		ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(matter.getProcInstId()).singleResult();
		ActBusiness actBusiness = actBusinessService.get(pi.getBusinessKey());
		Matter matter1 = matterService.get(actBusiness.getTableId());
		if (StrUtil.isNotBlank(matter.getField0043())){
			matter1.setField0043(matter.getField0043());
		}
		//承办人
		if (StrUtil.isNotBlank(matter.getApplyUser())){
			matter1.setApplyUser(matter.getApplyUser());
		}
		//直接领导
		if (StrUtil.isNotBlank(matter.getField0014())){
			matter1.setField0014(matter.getField0014());
		}
		//科长
		if (StrUtil.isNotBlank(matter.getField0020())){
			matter1.setField0020(matter.getField0020());
		}
		//书记批示
		if (StrUtil.isNotBlank(matter.getField0021())){
			matter1.setField0021(matter.getField0021());
		}
		//处理前
		if (StrUtil.isNotBlank(matter.getBeforeProcessImg())){
			matter1.setBeforeProcessImg(matter.getBeforeProcessImg());
		}
		//处理中
		if (StrUtil.isNotBlank(matter.getInProcessImg())){
			matter1.setInProcessImg(matter.getInProcessImg());
		}
		//处理后
		if (StrUtil.isNotBlank(matter.getAfterProcessImg())){
			matter1.setAfterProcessImg(matter.getAfterProcessImg());
		}
		matterService.update(matter1);
		return new ResultUtil<Object>().setSuccessMsg("操作成功");
	}
	@RequestMapping(value = "/updateRecv", method = RequestMethod.POST)
	@ApiOperation(value = "更新流程表信息")
	public Result<Object> updateRecv(@ModelAttribute Matter matter) {
		Matter matter1 = matterService.get(matter.getId());
		if (matter.getField0039() != null){
			matter1.setField0039(matter.getField0039());
		}
		if (matter.getField0040() != null){
			matter1.setField0040(matter.getField0040());
		}
		//派单员回执
		if (StrUtil.isNotBlank(matter.getField0041())){
			matter1.setField0041(matter.getField0041());
		}
		matterService.update(matter1);
		return new ResultUtil<Object>().setSuccessMsg("操作成功");
	}

	@RequestMapping(value = "/getDelegateUsers", method = RequestMethod.GET)
	@ApiOperation(value = "获取转派人员列表")
	public Result<ProcessNodeVo> getDelegateUsers(@RequestParam String procInstId) {
		return new ResultUtil<ProcessNodeVo>().setData(matterService.getDelegateUsers(procInstId));
	}

	@RequestMapping(value = "/getPassUsers", method = RequestMethod.GET)
	@ApiOperation(value = "获取流程通过人员列表")
	public Result<ProcessNodeVo> getPassUsers(@RequestParam String procInstId) {
		return new ResultUtil<ProcessNodeVo>().setData(matterService.getPassUsers(procInstId));
	}

	@RequestMapping(value = "/getBackUsers", method = RequestMethod.GET)
	@ApiOperation(value = "获取流程驳回人员列表")
	public Result<ProcessNodeVo> getBackUsers(@RequestParam String procInstId,@RequestParam String nodeId) {
		return new ResultUtil<ProcessNodeVo>().setData(matterService.getBackUsers(procInstId,nodeId));
	}

	@RequestMapping(value = "/todoList", method = RequestMethod.GET)
	@ApiOperation(value = "代办列表")
	public Result<Object> todoList(@RequestParam(required = false) String name,
								   @RequestParam(required = false) String categoryId,
								   @RequestParam(required = false) Integer priority,
								   @ModelAttribute SearchVo searchVo,
								   @ModelAttribute PageVo pageVo){

		ActPage<TaskVo> page = new ActPage<TaskVo>();
		List<TaskVo> list = new ArrayList<>();
		List<User> users = new ArrayList<>();
		User user = securityUtil.getCurrUser();
		boolean isPaidan = false;
		for (Role r : user.getRoles()){
			if (r.getName().indexOf("网格员") >= 0){
				isPaidan = true;
				break;
			}
		}
		if (isPaidan){
			List<User> rolesUser = userService.findByRoleName("ROLE_网格员");
			users.addAll(rolesUser);
		}else{
			users.add(user);
		}
		List<Task> allTaskList = new ArrayList<>();
		users.forEach(u->{
			String userId = u.getId();
			//获取处理中&被委托
			TaskQuery query = taskService.createTaskQuery().taskCandidateOrAssigned(userId);
			// 多条件搜索
			if ("createTime".equals(pageVo.getSort()) && "asc".equals(pageVo.getOrder())) {
				query.orderByTaskCreateTime().asc();
			} else if ("priority".equals(pageVo.getSort()) && "asc".equals(pageVo.getOrder())) {
				query.orderByTaskPriority().asc();
			} else if ("priority".equals(pageVo.getSort()) && "desc".equals(pageVo.getOrder())) {
				query.orderByTaskPriority().desc();
			} else {
				query.orderByTaskCreateTime().desc();
			}
//			if (StrUtil.isNotBlank(name)) {
//				query.taskNameLike("%" + name + "%");
//			}
			if (StrUtil.isNotBlank(categoryId)) {
				query.taskCategory(categoryId);
			}
			if (priority != null) {
				query.taskPriority(priority);
			}
			if (StrUtil.isNotBlank(searchVo.getStartDate()) && StrUtil.isNotBlank(searchVo.getEndDate())) {
				Date start = DateUtil.parse(searchVo.getStartDate());
				Date end = DateUtil.parse(searchVo.getEndDate());
				query.taskCreatedAfter(start);
				query.taskCreatedBefore(DateUtil.endOfDay(end));
			}
			page.setTotalElements((page.getTotalElements() == null?0:page.getTotalElements()) + query.count());
			int first = (pageVo.getPageNumber() - 1) * pageVo.getPageSize();
			List<Task> taskList = query.listPage(first, pageVo.getPageSize());
			allTaskList.addAll(taskList);
		});

		ArrayList<Task> tmpList = new ArrayList<>();
		ArrayList<String> taskIds= new ArrayList<>();
		//去重
		allTaskList.forEach(e->{
			if (!taskIds.contains(e.getId())){
				taskIds.add(e.getId());
				tmpList.add(e);
			}
		});

		// 转换vo
		tmpList.forEach(e -> {
			TaskVo tv = new TaskVo(e);
			// 关联委托人
			if(StrUtil.isNotBlank(tv.getOwner())){
				tv.setOwner(userService.get(tv.getOwner()).getUsername());
			}
			List<IdentityLink> identityLinks = runtimeService.getIdentityLinksForProcessInstance(tv.getProcInstId());
			for(IdentityLink ik : identityLinks){
				// 关联发起人
				if("starter".equals(ik.getType())&&StrUtil.isNotBlank(ik.getUserId())){
					tv.setApplyer(userService.get(ik.getUserId()).getUsername());
				}
			}
			// 关联流程信息
			ActProcess actProcess = actProcessService.get(tv.getProcDefId());
			if(actProcess!=null){
				tv.setProcessName(actProcess.getName());
				tv.setRouteName(actProcess.getRouteName());
			}
			// 关联业务key
			ProcessInstance pi = runtimeService.createProcessInstanceQuery().processInstanceId(tv.getProcInstId()).singleResult();
			tv.setBusinessKey(pi.getBusinessKey());
			ActBusiness actBusiness = actBusinessService.get(pi.getBusinessKey());
			if(actBusiness!=null){
				tv.setTableId(actBusiness.getTableId());
				tv.setName(actBusiness.getTitle());
				tv.setOwner(actBusiness.getUserId());
				if ("matter".equals(tv.getRouteName())){
					Matter matter = matterService.get(tv.getTableId());
					if (StrUtil.isBlank(name) || matter.getField0001().indexOf(name) >= 0){
						//12345
						tv.setExtra(JSON.toJSONStringWithDateFormat(matter,"yyyy-MM-dd HH:mm:ss"));
						list.add(tv);
					}
					//否则过滤掉此条数据
				}
			}else {
				list.add(tv);
			}

		});
		page.setContent(list);
		return new ResultUtil<Object>().setData(page);
	}

}
